package sjtu.pirate.report;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import biz.source_code.miniTemplator.MiniTemplator.TemplateSyntaxException;

import sjtu.pirate.analyzer.PirateAnalyzer;
import sjtu.pirate.util.FileUtil;
import sjtu.pirate.util.StringUtil;

/**
 * @author wilbur.ma@qq.com
 * @date 2011.05.31
 * Report class generate reports.
 */
public abstract class Report {
	protected String templatesDir, targetDir;
	protected String[][] staticItems;
	protected Set<String> omittedItems;
	protected List<ReportTemplate> templates;
	
	public Report() {
		templatesDir = targetDir = null;
		staticItems = null;
		omittedItems = null;
		templates = null;
	}
	
	public Report(String templatesDir, String targetDir, PirateAnalyzer analyzer) 
			throws TemplateSyntaxException, IOException {
		this(templatesDir, targetDir, new String[0][0], analyzer);
	}
	
	public Report(String templatesDir, String targetDir, String[][]staticItems, PirateAnalyzer analyzer)
			throws TemplateSyntaxException, IOException {
		init(templatesDir, targetDir, staticItems, analyzer);
	}

	public Report(String templatesDir, String targetDir, String[][] staticItems, 
			Set<String> omittedItems, PirateAnalyzer analyzer) 
			throws TemplateSyntaxException, IOException {
		init(templatesDir, targetDir, staticItems, omittedItems, analyzer);
	}
	
	protected void init(String templatesDir, String targetDir, String[][]staticItems, PirateAnalyzer analyzer)
			throws TemplateSyntaxException, IOException {
		init(templatesDir, targetDir, staticItems, new HashSet<String>(2), analyzer);
		omittedItems.add(".hg");
		omittedItems.add(".svn");
	}
	
	protected void init(String templatesDir, String targetDir, String[][] staticItems, 
			Set<String> omittedItems, PirateAnalyzer analyzer) 
			throws TemplateSyntaxException, IOException {
		this.templatesDir = templatesDir;
		this.targetDir = targetDir;
		this.staticItems = staticItems;
		this.omittedItems = omittedItems;
		this.templates = new ArrayList<ReportTemplate>();
		initReportTemplates(analyzer);
	}
	
	protected abstract void initReportTemplates(PirateAnalyzer analyzer)
		throws TemplateSyntaxException, IOException;
	
	protected void prepareStaticItems() throws IOException {
		for (int i=0;i<staticItems.length;i++) {
			String item = StringUtil.joinPath(staticItems[i]);
			String targetItem = staticItems[i][staticItems[i].length-1];
			File curItem = new File(StringUtil.joinPath(templatesDir, item));
			if (!curItem.exists())
				throw new IOException(curItem.getAbsolutePath() + " does not exists.");
			
			if (curItem.isFile()) {
				FileUtil.copy(curItem.getAbsolutePath(), StringUtil.joinPath(targetDir, targetItem));
			} else {
				for (String name: curItem.list()) {
					if (omittedItems.contains(name))
						continue;
					FileUtil.copy(
							StringUtil.joinPath(curItem.getAbsolutePath(), name), 
							StringUtil.joinPath(targetDir, targetItem, name)
					);
				}
			}
		}
	}
	
	public void generate() throws IOException {
		prepareStaticItems();
		for (ReportTemplate rt : templates) {
			rt.compile();
			rt.generateOutputFile();
		}
	}
}
